// -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- -

float4x4 obj2projection;
float4x4 obj2world;
float4x4 world2obj;

float3 eyePosition;

// -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- -

float4 materialAmbient = float4 (0.1, 0.1, 0.1, 1.0); // ignored
float4 materialDiffuse = float4 (0.4, 0.4, 0.9, 0.4);
float4 materialSpecular = float4 (0.5, 0.5, 0.5, 1.0);
float shininess = 50;

float4 lightAmbient = float4 (0.2, 0.2, 0.2, 1.0); // ignored
float4 lightDiffuse = float4 (0.9, 0.9, 0.9, 1.0);
float4 lightSpecular = float4 (0.9, 0.9, 0.9, 1.0);
float3 lightPosition;

float foamPower = 0.5;
float foamScale = 0.8;

float movementRange = 0.1;
float timeScale = 0.0005;
float time = 0;

float attA = 1.0;
float attB = 0.00001;
float attC = 0.000001;

float considerAlpha = 0.0; // ignored

// -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- -

texture diffuseTexture;

sampler diffuseTextureSampler = sampler_state
{
	texture = <diffuseTexture>;
	AddressU = WRAP;
	AddressV = WRAP;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = POINT;
};

texture additionalTexture;

sampler additionalTextureSampler = sampler_state
{
	texture = <additionalTexture>;
	AddressU = WRAP;
	AddressV = WRAP;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = POINT;
};

// -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- -

struct VShaderInput
{
float4 position : POSITION;
float3 normal   : NORMAL;
float3 binormal : BINORMAL;
float3 tangent  : TANGENT;
float2 tex0     : TEXCOORD0;
};

struct PShaderInput
{
float4 hpos : POSITION;
float4 col0 : COLOR0;
float4 col1 : COLOR1;
float2 tex0 : TEXCOORD0;
float3 L    : TEXCOORD1;
float3 V    : TEXCOORD2;
float3 N    : TEXCOORD3;
float3 TBN0 : TEXCOORD4;
float3 TBN1 : TEXCOORD5;
float3 TBN2 : TEXCOORD6;
};

// -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- -

PShaderInput vs_water( VShaderInput input )
{
	PShaderInput result = (PShaderInput)0;
	result.hpos = mul( input.position, obj2projection );
	result.tex0 = input.tex0;

	float3 P = mul( input.position, obj2world );
	
	result.L = lightPosition - P;
	result.V = eyePosition - P;

	float3x3 tex2obj = float3x3(input.tangent, input.binormal, input.normal);
	float3x3 tex2world = mul(tex2obj, (float3x3)obj2world);

	result.TBN0 = tex2world[0];
    result.TBN1 = tex2world[1];
    result.TBN2 = tex2world[2];

	return result;
}

float4 ps_water( PShaderInput input ) : COLOR0
{
	float3 L = normalize( input.L );
	float3 V = normalize( input.V );
	float3 H = normalize( L + V );

	float2 offset1 = float2(sin(time*timeScale*0.97) + 23.7, -cos(time*timeScale*1.13)) * movementRange;
	float2 offset2 = float2(cos(time*timeScale*1.03) + 7.7, sin(time*timeScale*0.89) + 34.7) * movementRange;
	float4 foam1 = tex2D ( diffuseTextureSampler, (input.tex0 + offset1) * foamScale );
	float4 foam2 = tex2D ( additionalTextureSampler, (input.tex0 + offset2) * foamScale );
	float4 foam = (foam1 + foam2) * foamPower;

	float3x3 tex2world = float3x3(normalize(input.TBN0), normalize(input.TBN1), normalize(input.TBN2));
	float3 N = (foam1 + foam2).a;
	N = mul(N, tex2world);
	
	float Llength = length(input.L);
	float attenuation = attA + Llength*(attB + Llength*attC); 

	float4 specularPower = lightSpecular * materialSpecular * pow( saturate( dot (H, N) ), shininess ) / attenuation;

	float4 diffuseTexel = materialDiffuse * lightDiffuse;
	float4 output = diffuseTexel + specularPower + foam;
	output.a = materialDiffuse.a+ foam.a;
	return output;
}

technique Water
{
	pass P0
	{
		AlphaBlendEnable = TRUE;
        DestBlend = INVSRCALPHA;
        SrcBlend = SRCALPHA;
		vertexShader = compile vs_2_0 vs_water();
		pixelShader = compile ps_2_0 ps_water();
	}
}

// -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- - -- -
